// =============================================
// FD VHS Chroma Blur
// Made by Ubik and Claude 2026
// =============================================
// Separates luma and chroma, blurs chroma
// horizontally with a low-pass filter
// (simulating VHS 0.6 MHz chroma bandwidth).
// Luma image remains sharp.
// Connect video source to video in 1.
// =============================================

// ISADORA_PLUGIN_DESC("VHS Chroma Blur - separates luma and chroma, blurs chroma horizontally (like VHS 0.6 MHz chroma bandwidth), recombines. Luma stays sharp.")

// ISADORA_FLOAT_PARAM(chroma_blur_width, cbwt, 0.0, 1.0, 0.35, "How wide chroma spreads horizontally. 0 = no blur, 1 = heavy VHS smear.")
// ISADORA_FLOAT_PARAM(luma_sharpness, lmsh, 0.0, 1.0, 1.0, "Sharpness of luma relative to chroma. 1 = luma fully unaffected, 0 = both equally blurred.")

uniform float chroma_blur_width;
uniform float luma_sharpness;
uniform vec3 iResolution;
uniform sampler2D tex0;

void main()
{
    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    vec2 texel = 1.0 / iResolution.xy;

    // Original pixel for sharp luma reference
    vec4 orig = texture2D(tex0, uv);
    float luma = dot(orig.rgb, vec3(0.299, 0.587, 0.114));

    // Horizontal chroma blur: asymmetric low-pass filter (more smear right)
    float blurPixels = chroma_blur_width * 24.0;

    float w0 = 0.227;
    float w1 = 0.194;
    float w2 = 0.144;
    float w3 = 0.094;
    float w4 = 0.053;

    vec3 c0  = texture2D(tex0, uv).rgb;
    vec3 cR1 = texture2D(tex0, uv + vec2(texel.x * blurPixels * 0.5,  0.0)).rgb;
    vec3 cR2 = texture2D(tex0, uv + vec2(texel.x * blurPixels * 1.0,  0.0)).rgb;
    vec3 cR3 = texture2D(tex0, uv + vec2(texel.x * blurPixels * 1.5,  0.0)).rgb;
    vec3 cR4 = texture2D(tex0, uv + vec2(texel.x * blurPixels * 2.0,  0.0)).rgb;
    vec3 cL1 = texture2D(tex0, uv - vec2(texel.x * blurPixels * 0.25, 0.0)).rgb;
    vec3 cL2 = texture2D(tex0, uv - vec2(texel.x * blurPixels * 0.5,  0.0)).rgb;
    vec3 cL3 = texture2D(tex0, uv - vec2(texel.x * blurPixels * 0.75, 0.0)).rgb;
    vec3 cL4 = texture2D(tex0, uv - vec2(texel.x * blurPixels * 1.0,  0.0)).rgb;

    vec3 chromaBlurred = c0  * w0
                       + cR1 * w1 + cR2 * w2 + cR3 * w3 + cR4 * w4
                       + cL1 * (w1 * 0.6) + cL2 * (w2 * 0.6)
                       + cL3 * (w3 * 0.6) + cL4 * (w4 * 0.6);

    float weightSum = w0 + w1 + w2 + w3 + w4
                    + (w1 + w2 + w3 + w4) * 0.6;
    chromaBlurred /= weightSum;

    // Recombine: sharp luma + blurred chrominance
    float chromaLuma = dot(chromaBlurred, vec3(0.299, 0.587, 0.114));
    vec3 chrominance = chromaBlurred - vec3(chromaLuma);
    float finalLuma = mix(chromaLuma, luma, luma_sharpness);

    vec3 result = clamp(vec3(finalLuma) + chrominance, 0.0, 1.0);
    gl_FragColor = vec4(result, orig.a);
}
